/*
 * CS_EVOLUTION_ITEM_UPGRADE.cpp
 *
 *  Created on: 2013. 6. 17.
 *      Author: mega@gamevil.com
 */

#include "../../Command.h"
#include "../../User.h"
#include "../../NLogic/Bag.h"
#include "../../NLogic/VirtualCurrency.h"
#include "../../NResource/Static.h"
#include "../../NUtil/Utils.h"

#include "../../GameLog.h"

namespace ProjectZ { namespace NCommand {

void SendFailEvolutionItemUpgrade(User * pUser, int res)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(res);
	*pAck << static_cast<uint8_t>(0);
	*pAck << static_cast<uint64_t>(0);
	*pAck << static_cast<uint8_t>(0);
	*pAck << static_cast<uint8_t>(0);
	*pAck << static_cast<uint16_t>(0);
	*pAck << static_cast<uint16_t>(0);
	*pAck << static_cast<uint16_t>(0);
	*pAck << static_cast<uint16_t>(0);
	pAck->MakePacket(CMD_SC_EVOLUTION_ITEM_UPGRADE);
	pUser->Send(pAck);
}

void Command::CS_EVOLUTION_ITEM_UPGRADE(User * pUser, ::Network::Packet * pPacket)
{
	/*
	 * /// 진화아이템 다시 뽑기(업그레이드 기존 진화 아이템을 재진화 시키는 경우 능력치 향상 있음)
	CS_EVOLUTION_ITEM_UPGRADE                                                         0x1806
	{
			   u8                  u8bag_type;                                                                      /// 가방 타입
			   u64                 u64item_seq;                                                           /// 가방에서 몇번째 슬롯
	}

	SC_EVOLUTION_ITEM_UPGRADE                                                         0x1807
	{
			   s16                 s16Ack;                                                                            /// 포인트 부족 등 ack
			   u8                  u8bag_type;                                                                      /// 가방 타입
			   u64                 u64item_seq;                                                           /// 가방에서 몇번째 슬롯

			   /// 변경된 아이템 진화 값들
			   u8  evolve_max;                                                                            /// 최대 진화 단계
			   u8        evolve_step;                                                                      /// 현재 진화단계
			   u16      evolve_point;                                                                     /// 진화포인트
			   u16      evolve_eff;                                                                                   /// 진화당 증가하는 증가분(%)
			   u16      evolve_eff_value;                                                       /// 진화이펙트 값(누적)
	}
	 *
	 */
	PREPARE_PACKET;
	if (false == pUser->EndBattle_afterEffect())
	{
		SendFailEvolutionItemUpgrade(pUser, ACK_BATTLE_AFTEREFFECT);
		return;
	}

	char u8bag_type	= 0;
	uint64_t u64item_seq	= 0;

	*pPacket >> u8bag_type >> u64item_seq;

	NLogic::Bag * pBag = pUser->GetBag(static_cast<INVEN_BAG_TYPE>(u8bag_type));

	if (NULL == pBag)
	{
		DEBUGLOG("CS_EVOLUTION_ITEM_UPGRADE : pBag is NULL!! bagType=%d", u8bag_type);
		return;
	}

	NLogic::Item * pItem = pBag->GetItem(u64item_seq);

	if (NULL == pItem)
	{
		DEBUGLOG("CS_EVOLUTION_ITEM_UPGRADE : pItem is NULL!! u64item_seq=%d", u64item_seq);
		return;
	}

	if (pItem->GetData().evolve_step >= pItem->GetData().evolve_max)
	{
		DEBUGLOG("CS_EVOLUTION_ITEM_UPGRADE : Item Evolution Max!!");
		return;
	}

	int vcIndex = 0;
	switch (pItem->GetData().evolve_step)
	{
	case 0:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_1; break;
	case 1:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_2; break;
	case 2:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_3; break;
	case 3:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_4; break;
	case 4:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_5; break;
	case 5:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_6; break;
	case 6:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_7; break;
	case 7:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_8; break;
	case 8:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_9; break;
	case 9:		vcIndex = EM_VCINDEX_ITEM_EVOLUTION_10; break;
	case 10:	vcIndex = EM_VCINDEX_ITEM_EVOLUTION_11; break;
	case 11:	vcIndex = EM_VCINDEX_ITEM_EVOLUTION_12; break;
	case 12:	vcIndex = EM_VCINDEX_ITEM_EVOLUTION_13; break;
	case 13:	vcIndex = EM_VCINDEX_ITEM_EVOLUTION_14; break;
	case 14:	vcIndex = EM_VCINDEX_ITEM_EVOLUTION_15; break;
	}

	NResource::VCResource::Flyweight * pFly =
			NResource::Static::InstancePtr()->GetVCRef()->GetFly(vcIndex);

	if (NULL == pFly)
	{
		DEBUGLOG("CS_EVOLUTION_ITEM_UPGRADE : pFly is NULL!");
		return;
	}

	if (pUser->GetVirtualCurrency()->GetZen() < (pFly->_VC_PRICE * -1))
	{
		SendFailEvolutionItemUpgrade(pUser, ACK_NOT_ENOUGH_ZEN);
		return;
	}

	// 추가되는 효과값을 다시 계산하여 기존 효과값 보가 큰 경우 값 변경
	int newPer = NResource::Static::Instance().GetItemEvolution()->GetEvolveEffect(pUser);
	if (newPer > pItem->GetData().evolve_percent)
		pItem->GetData().evolve_percent = newPer;

	// 최대 진화 단계를 다시 계산하여 기존 보다 큰 경우 값 변경
	int newStep = NResource::Static::Instance().GetItemEvolution()->GetEvolveMaxStep(pUser, pItem->GetData().level);
	if (newStep > pItem->GetData().evolve_max)
		pItem->GetData().evolve_max = newStep;

	// 추가 진화포인트 지급
	int addPoint = NResource::Static::Instance().GetItemEvolution()->GetEvolveAddPoint(pUser, pItem->GetData().level);
	pItem->GetData().evolve_point += addPoint;

	// 아이템 진화에 필요한 포인트 계산
	int needPoint = NResource::Static::Instance().GetItemEvolution()->GetEvolveNeedPoint(pItem->GetData().evolve_step);

	while (pItem->GetData().evolve_point >= needPoint)
	{
		// 기본 효과값 증가
		int newValue = NUtil::AddPercentage(pItem->GetData().eff_value[0], pItem->GetData().evolve_percent);

		// 최소한 효과값 1은 증가
		if (newValue == pItem->GetData().eff_value[0])
			pItem->GetData().eff_value[0] += 1;
		else
			pItem->GetData().eff_value[0] = newValue;

		pItem->GetData().evolve_step += 1;	// 진화 단계 갱신
		pItem->GetData().evolve_value += pItem->GetData().evolve_percent;	// 진화 효과값 누적
		pItem->GetData().evolve_point -= needPoint;	// 남은 진화 포인트 반영

		needPoint = NResource::Static::Instance().GetItemEvolution()->GetEvolveNeedPoint(pItem->GetData().evolve_step);
	}

	if (false == pItem->UpdateDatabaseItemInfo())
	{
		DEBUGLOG("CS_EVOLUTION_ITEM_UPGRADE : Item Update Fail!!");
		SendFailEvolutionItemUpgrade(pUser, ACK_DB_ERROR);
		return;
	}

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

	*pAck << static_cast<int16_t>(ACK_OK);
	*pAck << u8bag_type;
	*pAck << static_cast<uint64_t>(u64item_seq);
	*pAck << static_cast<uint8_t>(pItem->GetData().evolve_max);
	*pAck << static_cast<uint8_t>(pItem->GetData().evolve_step);
	*pAck << static_cast<uint16_t>(pItem->GetData().evolve_point);
	*pAck << static_cast<uint16_t>(pItem->GetData().evolve_percent);
	*pAck << static_cast<uint16_t>(pItem->GetData().evolve_value);
	*pAck << static_cast<uint16_t>(pItem->GetData().eff_value[0]);
	pAck->MakePacket(CMD_SC_EVOLUTION_ITEM_UPGRADE);
	pUser->Send(pAck);

	// VC 처리
	NLogic::NFunction::VCProcess(pUser, vcIndex);

	NGameLog::LogItemInfo(pUser, UPGRADE_EVOLUTION_ITEM, 1, 0, pItem);
}

} /*NCommand*/ } /*ProjectZ*/
